package com.wfw.feichat.utils;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.*;
import org.apache.http.conn.ssl.DefaultHostnameVerifier;
import org.apache.http.conn.util.PublicSuffixMatcher;
import org.apache.http.conn.util.PublicSuffixMatcherLoader;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author: wfw
 * @date: 2019-05-21 16:31
 */
@Slf4j
public class HttpClientUtils {
    private static RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(15000).setConnectTimeout(15000)
            .setConnectionRequestTimeout(15000).build();


    private HttpClientUtils() {
    }


    /**
     * 发送json的post请求
     *
     * @param httpUrl
     * @param params
     * @return
     */
    public static String sendHttpPostJson(String httpUrl, String params) {
        HttpPost httpPost = new HttpPost(httpUrl);
        return sendHttpRequestJson(params, httpPost);
    }

    /**
     * 发送json请求
     *
     * @param jsonString json字符串
     * @return
     */
    private static String sendHttpRequestJson(String jsonString, HttpEntityEnclosingRequestBase http) {
        Map<String, Object> params = (Map<String, Object>) JSON.parse(jsonString);
        return sendHttpRequest(params, http);
    }

    /**
     * 发送post或者put请求
     *
     * @param maps
     * @param http
     * @return
     */
    private static String sendHttpRequest(Map<String, Object> maps, HttpEntityEnclosingRequestBase http) {
        // 创建参数队列
        log.info("#####################" + maps);
        List<NameValuePair> parameters = new ArrayList<NameValuePair>(0);
        if (maps != null) {
            for (Map.Entry<String, Object> entry : maps.entrySet()) {
                // 封装请求参数到容器中
                if (entry.getValue() != null && !entry.getValue().equals("")) {
                    log.info("$$$$$$$$$$$$$$$$$$$$" + entry.getKey());
                    log.info("$$$$$$$$$$$$$$$$$$$$" + entry.getValue());
                    parameters.add(new BasicNameValuePair(entry.getKey(), entry.getValue().toString()));
                }
            }
        }
        log.info("@@@@@@@@@@@@@@@@" + parameters.size());
        try {
            StringEntity stringEntity = new StringEntity(parameters.toString(), "UTF-8");
            stringEntity.setContentType("application/json");
            http.setEntity(stringEntity);

        } catch (Exception e) {
            log.error("sendHttpPost(String httpUrl, Map<String, String> maps)", e);
        }
        return sendHttpPost(http);
    }

    /**
     * 发送 post请求（带文件）
     *
     * @param maps      参数
     * @param fileLists 附件
     */
    public static String sendHttpPost(String httpUrl, Map<String, Object> maps, List<File> fileLists) {
        HttpPost httpPost = new HttpPost(httpUrl);
        return sendHttpRequest(httpPost, maps, fileLists);
    }

    /**
     * 发送 post请求（带文件）
     *
     * @param maps      参数
     * @param fileLists 附件
     */
    private static String sendHttpRequest(HttpEntityEnclosingRequestBase http, Map<String, Object> maps,
                                          List<File> fileLists) {
        MultipartEntityBuilder meBuilder = MultipartEntityBuilder.create();
        for (String key : maps.keySet()) {
            meBuilder.addPart(key, new StringBody(maps.get(key).toString(), ContentType.TEXT_PLAIN));
        }
        for (File file : fileLists) {
            FileBody fileBody = new FileBody(file);
            meBuilder.addPart("files", fileBody);
        }
        HttpEntity reqEntity = meBuilder.build();
        http.setEntity(reqEntity);
        return sendHttpPost(http);
    }

    /**
     * 发送 get请求
     *
     * @param httpUrl
     */
    public static String sendHttpGet(String httpUrl) {
        HttpGet httpGet = new HttpGet(httpUrl);// 创建get请求
        return sendHttpPost(httpGet);
    }

    public static String sendHttpGetToken(String httpUrl, String token) {
        HttpGet httpGet = new HttpGet(httpUrl);// 创建get请求
        httpGet.setHeader("token", token);
        return sendHttpPost(httpGet);
    }

    /**
     * 发送 get请求Https
     *
     * @param httpUrl
     */
    public static String sendHttpsGet(String httpUrl) {
        HttpGet httpGet = new HttpGet(httpUrl);// 创建get请求
        return sendHttpsGet(httpGet);
    }

    /**
     * 发送Post请求
     *
     * @param httpPost
     * @return
     */
    private static String sendHttpPost(HttpRequestBase httpPost) {
        CloseableHttpClient httpClient = null;
        CloseableHttpResponse response = null;
        HttpEntity entity = null;
        String responseContent = null;
        try {
            // 创建默认的httpClient实例.
            httpClient = HttpClients.createDefault();
            httpPost.setConfig(requestConfig);
            // 执行请求
            response = httpClient.execute(httpPost);
            entity = response.getEntity();
            responseContent = EntityUtils.toString(entity, "UTF-8");
        } catch (Exception e) {
            log.error("sendHttpPost(HttpRequestBase httpPost)", e);
        } finally {
            try {
                // 关闭连接,释放资源
                if (response != null) {
                    response.close();
                }
                if (httpClient != null) {
                    httpClient.close();
                }
            } catch (IOException e) {
                log.error("sendHttpPost(HttpRequestBase httpPost)", e);
            }
        }
        return responseContent;
    }

    /**
     * 发送Get请求Https
     *
     * @param httpGet
     * @return
     */
    private static String sendHttpsGet(HttpGet httpGet) {
        CloseableHttpClient httpClient = null;
        CloseableHttpResponse response = null;
        HttpEntity entity = null;
        String responseContent = null;
        try {
            // 创建默认的httpClient实例.
            PublicSuffixMatcher publicSuffixMatcher = PublicSuffixMatcherLoader
                    .load(new URL(httpGet.getURI().toString()));
            DefaultHostnameVerifier hostnameVerifier = new DefaultHostnameVerifier(publicSuffixMatcher);
            httpClient = HttpClients.custom().setSSLHostnameVerifier(hostnameVerifier).build();
            httpGet.setConfig(requestConfig);
            // 执行请求
            response = httpClient.execute(httpGet);
            entity = response.getEntity();
            responseContent = EntityUtils.toString(entity, "UTF-8");
        } catch (Exception e) {
            log.error("sendHttpsGet(HttpGet httpGet)", e);
        } finally {
            try {
                // 关闭连接,释放资源
                if (response != null) {
                    response.close();
                }
                if (httpClient != null) {
                    httpClient.close();
                }
            } catch (IOException e) {
                log.error("sendHttpsGet(HttpGet httpGet)", e);
            }
        }
        return responseContent;
    }

    /*******************************************************************************************************/

    public static String doPost(String url, String json) {
        CloseableHttpClient httpclient = HttpClientBuilder.create().build();
        HttpPost post = new HttpPost(url);
        String result = "";
        try {
            StringEntity s = new StringEntity(json.toString(), "UTF-8");
            s.setContentEncoding("UTF-8");
            s.setContentType("application/json");// 发送json数据需要设置contentType
            post.setEntity(s);
            HttpResponse res = httpclient.execute(post);
            if (res.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                result = EntityUtils.toString(res.getEntity());// 返回json格式：
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return result;
    }

    public static String doPostToken(String url, String json, String token) {
        CloseableHttpClient httpclient = HttpClientBuilder.create().build();
        HttpPost post = new HttpPost(url);
        post.setHeader("Content-type", "application/json; charset=UTF-8");
        post.setHeader("token", token);
        String result = "";
        try {
            StringEntity s = new StringEntity(json.toString(), "UTF-8");
            s.setContentEncoding("UTF-8");
            s.setContentType("application/json");// 发送json数据需要设置contentType
            post.setEntity(s);
            HttpResponse res = httpclient.execute(post);
            if (res.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                result = EntityUtils.toString(res.getEntity());// 返回json格式：
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return result;
    }

    public static String httpClientUploadFile(MultipartFile file) {
        final String remote_url = "http://192.168.1.99:8080/demo/file/upload";// 第三方服务器请求地址
        CloseableHttpClient httpClient = HttpClients.createDefault();
        String result = "";
        try {
            String fileName = file.getOriginalFilename();
            HttpPost httpPost = new HttpPost(remote_url);
            MultipartEntityBuilder builder = MultipartEntityBuilder.create();
            builder.addBinaryBody("file", file.getInputStream(), ContentType.MULTIPART_FORM_DATA, fileName);// 文件流
            builder.addTextBody("filename", fileName);// 类似浏览器表单提交，对应input的name和value
            HttpEntity entity = builder.build();
            httpPost.setEntity(entity);
            HttpResponse response = httpClient.execute(httpPost);// 执行提交
            HttpEntity responseEntity = response.getEntity();
            if (responseEntity != null) {
                // 将响应内容转换为字符串
                result = EntityUtils.toString(responseEntity, Charset.forName("UTF-8"));
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                httpClient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return result;
    }

    public static String httpClientUploadMultipartFile(String remote_url, MultipartFile file) {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        String result = "";
        try {
            String fileName = file.getOriginalFilename();
            HttpPost httpPost = new HttpPost(remote_url);
            MultipartEntityBuilder builder = MultipartEntityBuilder.create();
            builder.addBinaryBody("filename", file.getInputStream(), ContentType.MULTIPART_FORM_DATA, fileName);// 文件流
            //builder.addTextBody("name", fileName);// 类似浏览器表单提交，对应input的name和value
            HttpEntity entity = builder.build();
            httpPost.setEntity(entity);
            HttpResponse response = httpClient.execute(httpPost);// 执行提交
            HttpEntity responseEntity = response.getEntity();
            if (responseEntity != null) {
                // 将响应内容转换为字符串
                result = EntityUtils.toString(responseEntity, Charset.forName("UTF-8"));
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                httpClient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return result;
    }

    public static String httpClientUploadFilePost(String url, InputStream in, String fileName) {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        String result = "";
        try {
            HttpPost httpPost = new HttpPost(url);
            MultipartEntityBuilder builder = MultipartEntityBuilder.create();
            builder.addBinaryBody("file", in, ContentType.MULTIPART_FORM_DATA, fileName);// 文件流
            builder.addTextBody("filename", fileName);// 类似浏览器表单提交，对应input的name和value
            HttpEntity entity = builder.build();
            httpPost.setEntity(entity);
            HttpResponse response = httpClient.execute(httpPost);// 执行提交
            HttpEntity responseEntity = response.getEntity();
            if (responseEntity != null) {
                // 将响应内容转换为字符串
                result = EntityUtils.toString(responseEntity, Charset.forName("UTF-8"));
            }
        } catch (IOException e) {
            log.error("IOException-httpClientUploadFilePost", e);
        } catch (Exception e) {
            log.error("Exception-httpClientUploadFilePost", e);
        } finally {
            try {
                httpClient.close();
            } catch (IOException e) {
                log.error("IOException-httpClientUploadFilePost", e);
            }
        }
        return result;
    }

    /**
     * 发送 post请求
     *
     * @param httpUrl 地址
     */
    public String sendHttpRequest(String httpUrl) {
        HttpPost httpPost = new HttpPost(httpUrl);// 创建httpPost
        return sendHttpPost(httpPost);
    }

    /**
     * 发送put请求
     */
    public String sendHttpPut(String httpUrl) {
        HttpPut httpPut = new HttpPut(httpUrl);
        return sendHttpPost(httpPut);
    }

    /**
     * 发送json的put请求
     *
     * @param httpUrl
     * @param params
     * @return
     */
    public String sendHttpPutJson(String httpUrl, String params) {
        HttpPut httpPut = new HttpPut(httpUrl);
        return sendHttpRequestJson(params, httpPut);
    }

    /**
     * 发送key1=value1&key2=value2 参数格式的参数POST
     *
     * @param params
     * @param httpUrl
     * @return
     */
    public String sendHttpPost(String params, String httpUrl) {
        HttpPost httpPost = new HttpPost(httpUrl);
        return sendHttpRequest(params, httpPost);
    }

    /**
     * 发送Get请求
     *
     * @param httpPost
     * @return
     */
//    private String sendHttpGet(HttpGet httpGet) {
//        CloseableHttpClient httpClient = null;
//        CloseableHttpResponse response = null;
//        HttpEntity entity = null;
//        String responseContent = null;
//        try {
//            // 创建默认的httpClient实例.
//            httpClient = HttpClients.createDefault();
//            httpGet.setConfig(requestConfig);
//            // 执行请求
//            response = httpClient.execute(httpGet);
//            entity = response.getEntity();
//            responseContent = EntityUtils.toString(entity, "UTF-8");
//        } catch (Exception e) {
//            e.printStackTrace();
//        } finally {
//            try {
//                // 关闭连接,释放资源
//                if (response != null) {
//                    response.close();
//                }
//                if (httpClient != null) {
//                    httpClient.close();
//                }
//            } catch (IOException e) {
//                e.printStackTrace();
//            }
//        }
//        return responseContent;
//    }

    /**
     * 发送key1=value1&key2=value2 参数格式的参数put
     *
     * @param params
     * @param httpUrl
     * @return
     */
    public String sendHttpPut(String params, String httpUrl) {
        HttpPut httpPut = new HttpPut(httpUrl);
        return sendHttpRequest(params, httpPut);
    }

    /**
     * 发送HTTP请求
     *
     * @param params 参数(格式:key1=value1&key2=value2)
     */
    private String sendHttpRequest(String params, HttpEntityEnclosingRequestBase http) {
        try {
            // 设置参数
            StringEntity stringEntity = new StringEntity(params, "UTF-8");
            stringEntity.setContentType("application/x-www-form-urlencoded");
            http.setEntity(stringEntity);
        } catch (Exception e) {
            log.error("sendHttpPost(String httpUrl, String params) Error", e);
        }
        return sendHttpPost(http);
    }

    /**
     * @param httpUrl
     * @param map
     * @return
     */
    public String sendHttpPost(String httpUrl, Map<String, Object> map) {
        HttpPost httpPost = new HttpPost(httpUrl);
        return sendHttpRequest(map, httpPost);
    }

    public String sendHttpPut(String httpUrl, Map<String, Object> map) {
        HttpPut httpPut = new HttpPut(httpUrl);
        return sendHttpRequest(map, httpPut);
    }

    /**
     * 发送 put（带文件）
     *
     * @param maps      参数
     * @param fileLists 附件
     */
    public String sendHttpPut(String httpUrl, Map<String, Object> maps, List<File> fileLists) {
        HttpPut httpPut = new HttpPut(httpUrl);
        return sendHttpRequest(httpPut, maps, fileLists);
    }

    /**
     * 发送delete请求
     *
     * @param httpUrl
     * @return
     */
    public String sendHttpDelete(String httpUrl) {
        HttpDelete httpDelete = new HttpDelete(httpUrl);
        return sendHttpPost(httpDelete);
    }
}
